package com.ben.multiple.message.base.tencent;

import com.ben.multiple.message.base.MessageClient;
import com.ben.multiple.message.base.MessageProperties;
import com.ben.multiple.message.biz.model.MessageResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20190711.models.SendStatus;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author BenJin Yin
 * @date 2020/7/23
 */
@Slf4j
@AllArgsConstructor
public class TencentMessageClient implements MessageClient {
    private final MessageProperties.Tencent properties;

    @Override
    public MessageProperties.Type getType() {
        return MessageProperties.Type.TENCENT;
    }

    @Override
    public MessageResult sendMessage(Set<String> phoneSet, String templateCode, LinkedHashMap<String, Object> templateParam) {
        if (CollectionUtils.isEmpty(phoneSet) || !StringUtils.hasText(templateCode)) {
            return MessageResult.error("无短信模板类型或无手机号");
        }
        // 参数请求封装
        Map<String, Object> body = new HashMap<>(16);
        body.put("Action", "SendSms");
        body.put("Version", "2019-07-11");
        body.put("SmsSdkAppid", properties.getSmsSdkAppid());
        body.put("Sign", properties.getSign());
        body.put("PhoneNumberSet", phoneSet);
        body.put("TemplateID", templateCode);
        if (!CollectionUtils.isEmpty(templateParam)) {
            body.put("TemplateParamSet", new ArrayList<>(templateParam.values()));
        }
        log.info("请求腾讯云短信服务参数：{}", body);
        // 准备发起请求
        Credential credential = new Credential(properties.getSecretId(), properties.getSecretKey());
        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint(properties.getEndpoint());
        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);
        SmsClient client = new SmsClient(credential, "", clientProfile);
        ObjectMapper objectMapper = new ObjectMapper();
        String params = null;
        try {
            params = objectMapper.writeValueAsString(body);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        SendSmsRequest request = SendSmsRequest.fromJsonString(params, SendSmsRequest.class);
        SendSmsResponse response;
        try {
            response = client.SendSms(request);
        } catch (TencentCloudSDKException e) {
            // 请求异常，发送失败
            log.error("请求异常，发送失败，{}", body, e);
            return MessageResult.error("请求异常，发送失败。");
        }
        // 响应体为空，发送失败
        if (response == null) {
            log.error("响应体为空，发送失败：{}", body);
            return MessageResult.error("响应体为空，发送失败。");
        }
        SendStatus[] sendStatusSet = response.getSendStatusSet();
        // 响应详情为空，发送失败
        if (sendStatusSet == null || sendStatusSet.length == 0) {
            log.error("响应详情为空，发送失败：{}", response);
            return MessageResult.error("响应详情为空，发送失败。");
        }
        // 响应成功
        MessageResult result = MessageResult.success();
        result.setRequestId(response.getRequestId());
        List<MessageResult.ResultDetail> resultDetailList = Arrays.stream(sendStatusSet).map(obj -> {
            MessageResult.ResultDetail resultDetail = new MessageResult.ResultDetail();
            resultDetail.setCode(obj.getCode());
            resultDetail.setFee(obj.getFee());
            resultDetail.setMessage(obj.getMessage());
            resultDetail.setPhoneNumber(obj.getPhoneNumber());
            resultDetail.setSerialNo(obj.getSerialNo());
            return resultDetail;
        }).collect(Collectors.toList());
        result.setResultDetailList(resultDetailList);
        log.info("发送成功：{}", result);
        return result;
    }
}
